int x, y;
int kind;
int mouse_grabbed;
+ int status_changed;
} USBMouseState;
/* mostly the same values as the Bochs USB Mouse device */
s->dy += dy1;
s->dz += dz1;
s->buttons_state = buttons_state;
+ s->status_changed = 1;
}
static void usb_tablet_event(void *opaque,
s->y = y;
s->dz += dz;
s->buttons_state = buttons_state;
+ s->status_changed = 1;
}
static inline int int_clamp(int val, int vmin, int vmax)
switch(pid) {
case USB_TOKEN_IN:
if (devep == 1) {
- if (s->kind == USB_MOUSE)
- ret = usb_mouse_poll(s, data, len);
- else if (s->kind == USB_TABLET)
- ret = usb_tablet_poll(s, data, len);
+ if (s->kind == USB_MOUSE)
+ ret = usb_mouse_poll(s, data, len);
+ else if (s->kind == USB_TABLET)
+ ret = usb_tablet_poll(s, data, len);
+
+ if (!s->status_changed)
+ ret = USB_RET_NAK;
+ else
+ s->status_changed = 0;
+
} else {
goto fail;
}
s->dev.handle_data = usb_mouse_handle_data;
s->dev.handle_destroy = usb_mouse_handle_destroy;
s->kind = USB_TABLET;
+ s->status_changed = 0;
pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
s->dev.handle_data = usb_mouse_handle_data;
s->dev.handle_destroy = usb_mouse_handle_destroy;
s->kind = USB_MOUSE;
+ s->status_changed = 0;
pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
uint8_t buf[2048];
int len, max_len, err, ret;
- if (td->ctrl & TD_CTRL_IOC) {
- *int_mask |= 0x01;
+ if (!(td->ctrl & TD_CTRL_ACTIVE)){
+ ret = 1;
+ goto out;
}
-
- if (!(td->ctrl & TD_CTRL_ACTIVE))
- return 1;
/* TD is active */
max_len = ((td->token >> 21) + 1) & 0x7ff;
/* invalid pid : frame interrupted */
s->status |= UHCI_STS_HCPERR;
uhci_update_irq(s);
- return -1;
+ ret = -1;
+ goto out;
}
if (td->ctrl & TD_CTRL_IOS)
td->ctrl &= ~TD_CTRL_ACTIVE;
len < max_len) {
*int_mask |= 0x02;
/* short packet: do not update QH */
- return 1;
+ ret = 1;
+ goto out;
} else {
/* success */
- return 0;
+ ret = 0;
+ goto out;
}
} else {
switch(ret) {
}
td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
(err << TD_CTRL_ERROR_SHIFT);
- return 1;
+ ret = 1;
+ goto out;
case USB_RET_NAK:
td->ctrl |= TD_CTRL_NAK;
if (pid == USB_TOKEN_SETUP)
goto do_timeout;
- return 1;
+ ret = 1;
+ goto out;
case USB_RET_STALL:
td->ctrl |= TD_CTRL_STALL;
td->ctrl &= ~TD_CTRL_ACTIVE;
- return 1;
+ ret = 1;
+ goto out;
case USB_RET_BABBLE:
td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
td->ctrl &= ~TD_CTRL_ACTIVE;
/* frame interrupted */
- return -1;
+ ret = -1;
+ goto out;
}
}
+
+out:
+ /* If TD is inactive and IOC bit set to 1 then update int_mask */
+ if ((td->ctrl & TD_CTRL_IOC) && (!(td->ctrl & TD_CTRL_ACTIVE))) {
+ *int_mask |= 0x01;
+ }
+ return ret;
}
static void uhci_frame_timer(void *opaque)